package controllers

import (
	"net/http"
	"obsidian-plugin-server/middleware"
	"obsidian-plugin-server/models"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type DocumentController struct {
	DB *gorm.DB
}

// CreateDocumentRequest 创建文档请求
type CreateDocumentRequest struct {
	Title     string     `json:"title" binding:"required,max=255"`
	Content   string     `json:"content" binding:"required"`
	IsPublic  bool       `json:"is_public"`
	Password  *string    `json:"password"`
	Theme     string     `json:"theme" binding:"omitempty,oneof=github dark minimal notion obsidian"`
	ExpiresAt *time.Time `json:"expires_at"`
	Path      string     `json:"path" binding:"omitempty,max=512"`
}

// UpdateDocumentRequest 更新文档请求
type UpdateDocumentRequest struct {
	Title     *string    `json:"title" binding:"omitempty,max=255"`
	Content   *string    `json:"content"`
	IsPublic  *bool      `json:"is_public"`
	Password  *string    `json:"password"`
	Theme     *string    `json:"theme" binding:"omitempty,oneof=github dark minimal notion obsidian"`
	ExpiresAt *time.Time `json:"expires_at"`
	Path      *string    `json:"path" binding:"omitempty,max=512"`
}

// Index 获取当前用户的所有文档列表（供插件使用）
func (dc *DocumentController) Index(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	var documents []models.Document
	if err := dc.DB.Where("user_id = ?", user.ID).
		Preload("User").
		Order("created_at DESC").
		Find(&documents).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Database error",
			"message": err.Error(),
		})
		return
	}

	// 格式化响应数据，保持与插件期望字段一致
	response := make([]gin.H, 0, len(documents))
	for _, doc := range documents {
		response = append(response, gin.H{
			"uuid":       doc.UUID,
			"title":      doc.Title,
			"url":        "/d/" + doc.UUID,
			"is_public":  doc.IsPublic,
			"password":   doc.Password,
			"theme":      doc.Theme,
			"views":      doc.Views,
			"author":     doc.User.Name,
			"expires_at": doc.ExpiresAt,
			"is_expired": doc.IsExpired(),
			"created_at": doc.CreatedAt,
			"updated_at": doc.UpdatedAt,
			"path":       doc.Path,
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    response,
	})
}

// Store 上传新文档
func (dc *DocumentController) Store(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	var req CreateDocumentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"error":   "Validation failed",
			"errors":  err.Error(),
		})
		return
	}

	// 设置默认主题
	if req.Theme == "" {
		req.Theme = "github"
	}

	// 检查私有文档是否需要密码
	if !req.IsPublic && (req.Password == nil || *req.Password == "") {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"error":   "Validation failed",
			"message": "私有文档需要设置密码",
		})
		return
	}

	// 创建文档
	document := models.Document{
		UserID:    user.ID,
		Title:     req.Title,
		Content:   req.Content,
		Path:      req.Path,
		IsPublic:  req.IsPublic,
		Password:  req.Password,
		Theme:     req.Theme,
		ExpiresAt: req.ExpiresAt,
	}

	if err := dc.DB.Create(&document).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Database error",
			"message": err.Error(),
		})
		return
	}

	// 预加载用户信息
	dc.DB.Preload("User").First(&document, document.ID)

	c.JSON(http.StatusCreated, gin.H{
		"success": true,
		"message": "Document uploaded successfully",
		"data": gin.H{
			"uuid":       document.UUID,
			"title":      document.Title,
			"url":        "/d/" + document.UUID,
			"is_public":  document.IsPublic,
			"password":   document.Password,
			"theme":      document.Theme,
			"views":      document.Views,
			"author":     document.User.Name,
			"expires_at": document.ExpiresAt,
			"created_at": document.CreatedAt,
			"path":       document.Path,
		},
	})
}

// Show 获取单个文档详情
func (dc *DocumentController) Show(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	uuid := c.Param("uuid")
	var document models.Document
	if err := dc.DB.Where("uuid = ?", uuid).Preload("User").First(&document).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"success": false,
			"error":   "Not found",
			"message": "Document not found",
		})
		return
	}

	// 验证文档所有权
	if document.UserID != user.ID {
		c.JSON(http.StatusForbidden, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "You do not have permission to access this document",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data": gin.H{
			"uuid":         document.UUID,
			"title":        document.Title,
			"content":      document.Content,
			"url":          "/d/" + document.UUID,
			"is_public":    document.IsPublic,
			"password":     document.Password,
			"has_password": document.Password != nil && *document.Password != "",
			"theme":        document.Theme,
			"views":        document.Views,
			"author":       document.User.Name,
			"expires_at":   document.ExpiresAt,
			"is_expired":   document.IsExpired(),
			"created_at":   document.CreatedAt,
			"updated_at":   document.UpdatedAt,
			"path":         document.Path,
		},
	})
}

// Update 更新文档
func (dc *DocumentController) Update(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	uuid := c.Param("uuid")
	var document models.Document
	if err := dc.DB.Where("uuid = ?", uuid).First(&document).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"success": false,
			"error":   "Not found",
			"message": "Document not found",
		})
		return
	}

	// 验证文档所有权
	if document.UserID != user.ID {
		c.JSON(http.StatusForbidden, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "You do not have permission to update this document",
		})
		return
	}

	var req UpdateDocumentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"error":   "Validation failed",
			"errors":  err.Error(),
		})
		return
	}

	// 更新字段
	updates := make(map[string]interface{})
	if req.Title != nil {
		updates["title"] = *req.Title
	}
	if req.Content != nil {
		updates["content"] = *req.Content
	}
	if req.IsPublic != nil {
		updates["is_public"] = *req.IsPublic
		// 如果设为公开，清除密码
		if *req.IsPublic {
			updates["password"] = nil
		}
	}
	if req.Password != nil {
		updates["password"] = *req.Password
	}
	if req.Theme != nil {
		updates["theme"] = *req.Theme
	}
	if req.ExpiresAt != nil {
		updates["expires_at"] = *req.ExpiresAt
	}
	if req.Path != nil {
		updates["path"] = *req.Path
	}

	if err := dc.DB.Model(&document).Updates(updates).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Database error",
			"message": err.Error(),
		})
		return
	}

	// 重新加载文档和用户信息
	dc.DB.Preload("User").First(&document, document.ID)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Document updated successfully",
		"data": gin.H{
			"uuid":       document.UUID,
			"title":      document.Title,
			"url":        "/d/" + document.UUID,
			"is_public":  document.IsPublic,
			"password":   document.Password,
			"theme":      document.Theme,
			"views":      document.Views,
			"author":     document.User.Name,
			"expires_at": document.ExpiresAt,
			"updated_at": document.UpdatedAt,
			"path":       document.Path,
		},
	})
}

// Destroy 删除文档
func (dc *DocumentController) Destroy(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	uuid := c.Param("uuid")
	var document models.Document
	if err := dc.DB.Where("uuid = ?", uuid).First(&document).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"success": false,
			"error":   "Not found",
			"message": "Document not found",
		})
		return
	}

	// 验证文档所有权
	if document.UserID != user.ID {
		c.JSON(http.StatusForbidden, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "You do not have permission to delete this document",
		})
		return
	}

	if err := dc.DB.Delete(&document).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Database error",
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Document deleted successfully",
	})
}

